/* eslint-disable max-len */
import {
  AttachmentDto,
  AvatarDto,
  ListAvatarDto,
  ListCityDto,
  ProfileV2Dto,
  UserWithProfileV2Dto,
} from '@/shared/interfaces/generated';
import { PaymentSystem } from '@/shared/lib/getCardSystem';
import { createReducer, PayloadAction } from '@reduxjs/toolkit';
import _ from 'lodash';

import * as ProfileActions from './actions';

export interface Card {
  number: number;
  system: PaymentSystem;
}

interface IUser {
  name: string | null;
  authType?: UserWithProfileV2Dto['authType'];
  isPremium?: boolean;
  avatar: string | null;
  city: {
    id: number | null;
    name: string | null;
  };
  familyRole: string | null;
  dateOfBirth: string | null;
  phoneNumber: string | null;
}
export interface StateTypes {
  user: IUser;
  cities: {
    data: {
      id: number;
      name: string;
    }[];
    offset: number;
    isLoading: boolean;
  };
  cards: Card[];
  activeCard: Card | null;
  removeProfile: {
    loading: boolean;
    error: null | string;
    success: boolean;
  };
  getProfile: {
    loading: boolean;
    error: null | {
      name?: string;
      error?: string;
    };
    success: boolean;
  };
  editProfile: {
    loading: boolean;
    error: null | {
      name?: string;
      error?: string;
    };
    success: boolean;
  };
  avatarList: AvatarDto[];
  currentPDF: Partial<AttachmentDto> | null;
}

const initialState: StateTypes = {
  user: {
    name: '',
    avatar: '',
    isPremium: false,
    city: {
      id: 0,
      name: '',
    },
    familyRole: '',
    dateOfBirth: '',
    phoneNumber: '',
  },
  currentPDF: null,
  cards: [],
  activeCard: null,
  cities: {
    data: [],
    offset: 0,
    isLoading: false,
  },

  avatarList: [],

  getProfile: {
    loading: false,
    error: null,
    success: false,
  },
  editProfile: {
    loading: false,
    error: null,
    success: false,
  },
  removeProfile: {
    loading: false,
    error: null,
    success: false,
  },
};

export const profileReducer = createReducer(initialState, (builder) => {
  builder
    .addCase(ProfileActions.getProfile.pending.type, (state) => {
      state.getProfile = { ...initialState.getProfile };
      state.getProfile.loading = true;
    })
    .addCase(ProfileActions.getProfile.fulfilled.type, (state, action: PayloadAction<UserWithProfileV2Dto>) => {
      state.getProfile = { ...initialState.getProfile };
      state.getProfile.success = true;
      state.user = { ...action.payload.profile, authType: action.payload.authType };
    })
    .addCase(ProfileActions.getProfile.rejected.type, (state, action: PayloadAction<any>) => {
      state.getProfile.loading = false;
      state.getProfile.error = action.payload;
    })
    .addCase(ProfileActions.getCities.fulfilled, (state, action: PayloadAction<ListCityDto>) => {
      state.cities.data = _.uniqBy([...state.cities.data, ...action.payload.cities], 'id');
      state.cities.isLoading = false;
    })
    .addCase(ProfileActions.getCities.pending.type, (state) => {
      state.cities.isLoading = true;
    })
    .addCase(ProfileActions.getUniqueAvatarList.fulfilled.type, (state, action: PayloadAction<ListAvatarDto>) => {
      state.avatarList = action.payload.avatars.map((item) => item.avatar);
    })
    .addCase(ProfileActions.editProfile.pending.type, (state) => {
      state.editProfile.loading = true;
      state.editProfile.success = false;
    })
    .addCase(ProfileActions.editProfile.fulfilled.type, (state, action: PayloadAction<ProfileV2Dto>) => {
      state.editProfile.loading = false;
      state.editProfile.success = true;
      state.user = Object.assign(action.payload);
      state.user.isPremium = false;
    })
    .addCase(ProfileActions.editProfile.rejected.type, (state, action: PayloadAction<{ [key: string]: string }>) => {
      state.editProfile.loading = false;
      state.editProfile.error = action.payload;
    })
    .addCase(ProfileActions.removeProfile.fulfilled.type, (state) => {
      state.removeProfile.success = true;
      state.removeProfile.loading = false;
    })
    .addCase(ProfileActions.removeProfile.rejected.type, (state, action: PayloadAction<string>) => {
      state.removeProfile.error = action.payload;
    })
    .addCase(ProfileActions.setPagination, (state) => {
      state.cities.offset += 20;
    })
    .addCase(ProfileActions.clearCities, (state) => {
      state.cities.offset = 0;
      state.cities.data = [];
    })
    .addCase(ProfileActions.addPaymentCard, (state, action: PayloadAction<Card>) => {
      state.cards = [...state.cards, action.payload];
    })
    .addCase(ProfileActions.deletePaymentCard, (state, action: PayloadAction<Card>) => {
      state.cards = state.cards.filter((item) => item.number !== action.payload?.number);
    })
    .addCase(ProfileActions.setActiveCard, (state, action: PayloadAction<Card>) => {
      if (action.payload.number === state.activeCard?.number) {
        state.activeCard = null;
      } else state.activeCard = action.payload;
    })
    .addCase(ProfileActions.setPremium, (state) => {
      state.user.isPremium = !state.user.isPremium;
    });
});
